package com.wh1200.mybatis.xmlless.model

import com.wh1200.mybatis.xmlless.constant.*
import org.apache.ibatis.type.TypeHandler
import java.lang.reflect.Type

/**
 *
 * @author 吴昊
 * @since 0.0.1
 */
data class FieldMapping(
    val tableFieldInfo: XmllessTableFieldInfo,
    val joinInfo: JoinInfo?,
    val isKeyField: Boolean,
    val joinObjects: List<JoinObjectInfo>,
    /** 是否总数统计字段 */
    val isCount: Boolean,
    /** 是否插入时忽略 */
    val insertIgnore: Boolean,
    /** 是否自增主键 */
    val isAutoGeneratedKey: Boolean,
    /**  持久化类的属性名称 */
    val property: String,
    /** 是否查询时忽略 */
    val selectIgnore: Boolean,
    /** 字段类型 */
    val type: Type,
    val isNumberIdType: Boolean,
    val isStringType: Boolean,
    val isNumberType: Boolean,
    /** 是否更新时忽略 */
    val updateIgnore: Boolean,
    /** 是否json对象 */
    val isJsonObject: Boolean,
    /** 是否json数组 */
    val isJsonArray: Boolean,
    /**  mybatis的字段处理器 */
    private val typeHandlerName: String?,
    val handler: Class<out TypeHandler<*>>?,
    val isVersion: Boolean
) {

  val fieldWrapper = tableFieldInfo.fieldWrapper

  /** 是否最后修改时间字段 */
  val isLastModifiedBy = tableFieldInfo.isLastModifiedBy

  /** 是否最后修改时间字段 */
  val isLastModifiedDate = tableFieldInfo.isLastModifiedDate

  /**  对应数据库表的列名称 */
  val column: String = tableFieldInfo.column


  /** 是否创建人id字段 */
  private val isCreatedBy = tableFieldInfo.isCreatedBy

  /** 是否创建时间字段 */
  private val isCreatedDate = tableFieldInfo.isCreatedDate

  val isDeletedBy = tableFieldInfo.isDeletedBy

  val isDeletedDate = tableFieldInfo.isDeletedDate

  fun isDeleteOrUpdateInfoField(): Boolean {
    return isDeletedBy || isDeletedDate || isLastModifiedBy || isLastModifiedDate
  }

  fun getInsertPropertyExpression(prefix: String? = null): String {
    if (isCreatedDate || isLastModifiedDate || isDeletedDate) {
      val unwrapProperty = getPropertyExpression(prefix, false)
      return SYSDATE_INSERT_TEMPLATE.format(unwrapProperty, getPropertyExpression(prefix)).trimIndent()
    }
    if (isCreatedBy || isLastModifiedBy) {
      val unwrapProperty = getPropertyExpression(prefix, false)
      return CURRENT_USER_INSERT_TEMPLATE.format(unwrapProperty, getPropertyExpression(prefix)).trimIndent()
    }
    return getPropertyExpression(prefix)
  }

  fun getPropertyExpression(prefix: String? = null, wrap: Boolean = true): String {
    val template = if (wrap) {
      """$PROPERTY_PREFIX%s%s%s$PROPERTY_SUFFIX"""
    } else {
      """%s%s%s"""
    }
    return template.format(
        prefix ?: "", property,
        if (typeHandlerName != null) {
          ", ${Strings.HANDLER_PREFIX}${typeHandlerName}"
        } else {
          ""
        }
    )
  }

}
